package clases;

import java.util.Enumeration;
import java.util.Hashtable;
import main.Errores;
import main.Global;

/**
  *  4g3nt
  *  Copyright (C) 2008  Carlos Molinero y César Andrés
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *    You should have received a copy of the GNU General Public License
  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
public class Celula implements Runnable{
    private Hashtable _agentes=new Hashtable();
    private String _id;
    private Hashtable _hijos=new Hashtable();
    private String _padre;
    private BufferEntrada _inputBuffer= new BufferEntrada (10);
    
    public void sendMessage(Mensajes mensaje)
    {
    	switch (mensaje.getID())
    	{
    	case Mensajes.RESPUESTA:
    	{
    		/**
    		 * Mandamos el mensaje al padre
    		 */
    		Global.getCelula(_padre)._inputBuffer.insertarMensaje(mensaje);
    	}
    	case Mensajes.IDENTIFICACION:
    	{
    		/**
    		 * Mandamos el mensaje a todos los hijos
    		 */
    		Enumeration it_hijos = _hijos.keys();
    		while (it_hijos.hasMoreElements())
    		{
    			String var_idcelula = (String)_hijos.get(it_hijos.nextElement());
    			 Global.getCelula(var_idcelula)._inputBuffer.insertarMensaje(mensaje);
    		}
    	}
    	
    	}
    }
    public void setId(String id)
    {
    	_id= id;
		Global.setThread(new Thread(this, id));

    }
    public void setAgente(Agente agente)
    {
    	if ( _agentes.get(agente.getId())!=null)
    		{
    		Errores.insertar("Id= "+agente.getId()+" de agente esta repetido en la celul"+_id);	
    		}
    	else
    	{
    		_agentes.put(agente.getId(),agente);
    	}
    	
    }
    public void setHijo(String idCelula)
    {
    	if (_hijos.get(idCelula)!=null)
    		{
    		
    		Errores.insertar("Id= "+idCelula+" de hijo esta repetido en la celula"+_id);
    		}
    	else
    	{
    		_hijos.put(idCelula, idCelula);
    	}
   	
    }
    public void setPadre(String idCelula)
    {
    	_padre = idCelula;
    }
	public void run() {
		
		Mensajes mensaje = _inputBuffer.fetch();
		procesaMensaje(mensaje);
		
	}
	
	private void procesaMensaje(Mensajes mensaje)
	{	
		Global.escribir("<tr class=\"modo2\"″><td>Celula("+_id+") procesando: </td><td>"+mensaje.toString()+"</td></tr>");
		switch (mensaje.getID())
		{
		case Mensajes.EMPEZARTRABAJO :
		{
			break;
		}
		case Mensajes.FINALIZARTRABAJO :
		{
			break;
		}
		
		case Mensajes.IDENTIFICACION:
		{
			/**
			 * La celula manda la identificación a todos sus agentes
			 */
			Enumeration enumerador = _agentes.keys();
			while (enumerador.hasMoreElements())
			{
				Agente agente = (Agente)_agentes.get(enumerador.nextElement());
				agente.insertarMensaje(new Mensajes(mensaje));
			}
			break;
		}

		case Mensajes.RESPUESTA :
		{
			/**
			 * La celula manda al agente el mensaje
			 */
			ParesAC parAC = mensaje.getDestino();
			if (Global.getCelula(parAC.getCelula()).getID().equals(_id))
			{
				Agente var_agente= (Agente) _agentes.get(parAC.getAgente());
				var_agente.insertarMensaje(new Mensajes(mensaje));
			}
			break;
		}

		}
		run();
	}

	
	public boolean iqualsID(String id2) {
		return _id.equals(id2);
	}
	public String getID()
	{
			return _id;
		
	}
	public void print()
	{
		 Global.escribir("<li class=\"closed\"><span class=\"folder\">"+_id+"</span>");
		 Global.escribir("<ul>");
         		if (Global.getCelula(_padre)==null){Errores.insertar("Id "+_padre+", de padre de la celula"+_id+"no esta definido");}
         		Global.escribir("<li><span class=\"file\">Padre="+_padre+"</span></li>");
         		
         		Global.escribir("<li class=\"closed\"><span class=\"folder\">Hijos de "+_id+"</span>");
         		Global.escribir("<ul>");
         		Enumeration it_hijos =_hijos.keys();
         		while(it_hijos.hasMoreElements())
         		{	
         				String key = (String)_hijos.get(it_hijos.nextElement());
         				if (Global.getCelula(key)==null)
     					{
     						Errores.insertar("Id "+key+" de celula hijo en "+ _id +"no esta definido");         						
     					}
     				else{Global.getCelula(key).print();}
         				
         		}
         			
         			
         		Global.escribir("</ul>");
         		Global.escribir("<li>");
         		Global.escribir("<li class=\"closed\"><span class=\"folder\">Agentes de "+_id+"</span>");
         		Global.escribir("<ul>");
         		Enumeration it_agentes = _agentes.keys();
         		while (it_agentes.hasMoreElements())
         		{
         			Agente var_agente = (Agente)_agentes.get(it_agentes.nextElement());
         			var_agente.print();
         		}
         		Global.escribir("</ul>");
         		Global.escribir("<li>");

		 Global.escribir("</ul>");
		 Global.escribir("<li>");
	}
    public Agente getAgente(String id)
    {
    	return (Agente)_agentes.get(id);
    	
    }
    public String getPadre()
    {
    	return _padre;
    }
    public Agente haceTrabajo(String trabajo)
    {
		Enumeration it_agentes = _agentes.keys();
 		while (it_agentes.hasMoreElements())
 		{
 			Agente var_agente = (Agente)_agentes.get(it_agentes.nextElement());
                           /**
                            * corregir
                            */
                }
 		return null;
    	
    	
    }
}